package virtorina.server.domain;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import net.sf.jsr107cache.Cache;
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheManager;

import virtorina.server.PMF;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Label implements Serializable, Comparable<Label> {
	private static final long serialVersionUID = 1L;
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Long ID;
	@Persistent
	private String name;
	@Persistent
	private Integer count;
	private static Cache Labels;

	// (1)при запуске приложения создаётся статичный кэширующий объект для
	// класса
	static {
		try {
			Labels = CacheManager.getInstance().getCacheFactory()
					.createCache(Collections.emptyMap());
		} catch (CacheException e) {
		}
	}

	public Label(Long iD, String name) {
		super();
		ID = iD;
		this.name = name;
		this.count = 1;
	}

	// (2) нам очень часто нужно будет получать имена лейблов, используем
	// статичную ф-ию
	public static String getLabelName(Long id) {
		// (3) пробуем забрать из кэша
		String name = (String) Labels.get(id);
		if (name == null) {
			// (4a) в кэше этой штуки нет, лезем в базу
			PersistenceManager pm = PMF.get().getPersistenceManager();
			Label t;
			try {
				t = (Label) pm.getObjectById(id);
			} catch (Exception e) {
				// какое-то говно, скорее всего сейчас мы в версии разработчика,
				// и на локальной машине нет данного лейбла. добавляем в базу
				Label l = new Label(id, "Общий" + id);
				pm.makePersistent(l);
				pm.close();
				return l.getName();
			}
			// (4б) берём из базы, заливаем попутно в кэш
			Labels.put(id, t.getName());
			pm.close();
			// (4в) возвращаем имя
			return t.getName();
		}
		// в кэше есть, возвращаем оттуда
		return name;
	}

	public static LinkedList<String> getLabelsNames(Collection<Long> ids) {
		LinkedList<String> rslt = new LinkedList<String>();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Label t;
		String name;
		for (Long id : ids) {
			name = (String) Labels.get(id);
			if (name == null) {
				try {
					t = (Label) pm.getObjectById(id);
				} catch (Exception e) {
					continue;
				}
				Labels.put(id, t.getName());
				rslt.add(t.getName());
			} else {
				rslt.add(name);
			}
		}
		pm.close();
		return rslt;
	}
	public void incCount(){
		if (count==null){
			count = 1;
		}
		this.count++;
	}
	public static List<Label> getAll() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query q = pm.newQuery("select from " + Label.class.getName());
		q.setOrdering("count DESC");
		List<Label> rslt = (List<Label>) q.execute();
		LinkedList<Label> retrn = new LinkedList<Label>();
		for (Label r : rslt) {
			retrn.add(r);
			Labels.put(r.getID(), r.getName());
		}
		pm.close();
		return retrn;
	}

	public Label(String name, LinkedList<String> tags) {
		super();
		this.name = name;
	}

	public Label(String tq) {
		this.name = tq;
		this.count = 1;
	}

	public Long getID() {
		return ID;
	}

	public void setID(Long iD) {
		ID = iD;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public static Long saveLabel(String tq) {
		Label la = new Label(tq);
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Long t = pm.makePersistent(la).getID();
		pm.close();
		return t;
	}

	public Integer getCount() {
		return count;
	}

	public void setCount(Integer count) {
		this.count = count;
	}

	@Override
	public int compareTo(Label arg0) {
		return arg0.getCount() - this.getCount();
	}

	public void decCount() {
		this.count--;
		
	}

}
